﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using WorkFlowCore.IRepositories;
using WorkFlowCore.UserSelectors;
using WorkFlowCore.WorkTasks;

namespace WorkFlowCore.Workflows
{
    public class WorkflowNode 
    {
        public WorkflowNode()
        {
        }

        public WorkflowNode(Guid id, WorkflowId workflowId, string name, WorkNodeType nodeType, string drawingInfo, bool isWaitingAllUser, List<NodeUser> userSelectors, List<RejectNode> rejectNodes, ProveModeEnum proveMode, bool? isAutoHandleSameUserStep = null, bool? isIgnoreCreator = null)
        {
            Id = id;
            WorkflowId = workflowId;
            Name = name;
            NodeType = nodeType;
            DrawingInfo = drawingInfo;
            IsWaitingAllUser = isWaitingAllUser;
            UserSelectors = userSelectors;
            RejectNodes = rejectNodes;
            ProveMode = proveMode;
            IsAutoHandleSameUserStep = isAutoHandleSameUserStep;
            IsIgnoreCreator = isIgnoreCreator;
        }

        public void Update(string name, WorkNodeType nodeType, string drawingInfo, bool isWaitingAllUser, List<NodeUser> userSelectors, List<RejectNode> rejectNodes, ProveModeEnum proveMode,bool? isAutoHandleSameUserStep=null)
        {
            Name = name;
            NodeType = nodeType;
            DrawingInfo = drawingInfo;
            IsWaitingAllUser = isWaitingAllUser;
            UserSelectors = userSelectors;
            RejectNodes = rejectNodes;
            ProveMode = proveMode;
            IsAutoHandleSameUserStep = isAutoHandleSameUserStep;
        }
        /// <summary>
        /// 节点标识
        /// </summary>
        public Guid Id { get; set; }

        /// <summary>
        /// 所属流程号
        /// </summary>
        [Required]
        public WorkflowId WorkflowId { get; set; }

        /// <summary>
        /// 节点名称
        /// </summary>
        [Required]
        [StringLength(50)]
        public string Name { get; set; }

        /// <summary>
        /// 节点类型
        /// </summary>
        public WorkNodeType NodeType { get; set; }
        /// <summary>
        /// 绘制信息，前端绘制所需信息
        /// </summary>
        public string DrawingInfo { get; set; }
        /// <summary>
        /// 是否等待所有人处理（默认为否）
        /// </summary>
        public bool IsWaitingAllUser { get; set; }
        /// <summary>
        /// 用户选择器
        /// </summary>
        public List<NodeUser> UserSelectors { get; set; }

        /// <summary>
        /// 拒绝节点
        /// </summary>
        public List<RejectNode> RejectNodes { get; set; }

        /// <summary>
        /// 父节点id，只有左右子流程时，才会标记
        /// </summary>
        public Guid? SubProcessNodeId { get; set; }

        /// <summary>
        /// 审批模式：作为 IsWaitingAllUser 的补充
        /// </summary>
        public ProveModeEnum ProveMode { get; set; }
        /// <summary>
        /// 驳回模式
        /// </summary>
        public RejectModeEnum RejectMode {  get; set; }
        /// <summary>
        /// 自动处理同用户。
        /// 为 null（兼容早期版本，默认自动处理） 或者 true 时，自动处理
        /// </summary>
        public bool? IsAutoHandleSameUserStep { get; set; }
        /// <summary>
        /// 是否忽略创建人，当一个节点有多人审批时生效。
        /// 不为 null（兼容早期版本，默认不忽略） 且 为 true 时，才忽略
        /// </summary>
        public bool? IsIgnoreCreator { get; set; }

        /// <summary>
        /// 获取成员
        /// 根据选择器获取派发的成员
        /// </summary>
        /// <param name="workTask"></param>
        /// <returns></returns>
        public Dictionary<NodeUser.NodeHandleType, List<User>> GetHandleUsers(WorkTask workTask, UserSelectorManager userSelectorManager)
        {
            var result = new Dictionary<NodeUser.NodeHandleType, List<User>>();
            //如果没有 指定用户选择器或者指定的选择其中没有处理人员时，从默认选择器取人

            if (UserSelectors == null || UserSelectors.Count == 0 || !UserSelectors.Any(us => us.HandleType == NodeUser.NodeHandleType.Handle))
            {

                var defaultSelectors = userSelectorManager.GetDefaultUserSelectors();
                foreach (var defaultSelector in defaultSelectors)
                {
                    var selectionIds = defaultSelector.GetDefaultSelectionIds();
                    foreach (var selectionId in selectionIds)
                    {
                        var _users = defaultSelector.GetUsers(new SelectorInput
                        {
                            SelectionId = selectionId,
                            Expression = string.Empty,
                            WorkTask = workTask
                        });
                        //未指定任何人，那默认选择器选的人就是要处理的人
                        if (!result.ContainsKey(NodeUser.NodeHandleType.Handle))
                            result.Add(NodeUser.NodeHandleType.Handle, new List<User>());

                        if (_users != null) result[NodeUser.NodeHandleType.Handle].AddRange(_users);
                    }
                }
            }

            foreach (var selector in UserSelectors)
            {
                var userSelector = userSelectorManager.GetUserSelector(selector.SelectorId);
                foreach (var selection in selector.Selections)
                {
                    var _users = userSelector.GetUsers(new SelectorInput
                    {
                        SelectionId = selection.Id,
                        Expression = selector.Parameter,
                        WorkTask = workTask
                    });
                    if (!result.ContainsKey(selector.HandleType))
                        result.Add(selector.HandleType, new List<User>());

                    if (_users != null) result[selector.HandleType].AddRange(_users);

                }
            }
            return result;
        }



    }

    /// <summary>
    /// 流程节点类型
    /// </summary>
    public enum WorkNodeType
    {
        /// <summary>
        /// 开始
        /// </summary>
        Begin,
        /// <summary>
        /// 结束
        /// </summary>
        End,
        /// <summary>
        /// 普通
        /// </summary>
        Normal,
        /// <summary>
        /// 判断
        /// </summary>
        Judge,
        /// <summary>
        /// 会签，所有指向该节点的节点都要审批完成后到达
        /// </summary>
        Sign,
        /// <summary>
        /// 分发
        /// </summary>
        HandOut,
        /// <summary>
        /// 子流程，该节点不分配审批人，将自动跳转到子节点
        /// </summary>
        SubProcess,
        /// <summary>
        /// 子节点，普通节点一样，区别在于 子流程 SubProcess 要求其子流程的第一个节点必须是 child 类型的节点，不然将无法区分是否是子流程
        /// </summary>
        SubNode,
    }
    /// <summary>
    /// 审批模式
    /// </summary>
    public enum ProveModeEnum
    {
        /// <summary>
        /// 默认模式
        /// </summary>
        None=0,
        /// <summary>
        /// 全部审批通过才通过
        /// </summary>
        PassWhenAllPass = 1,
        /// <summary>
        /// 其中一个审批通过则通过
        /// </summary>
        PassWhenAnyPass = 2,
    }
    /// <summary>
    /// 驳回节点模式
    /// </summary>
    public enum RejectModeEnum
    {
        /// <summary>
        /// 退回到上一节点
        /// </summary>
        ToPreNode,
        /// <summary>
        /// 退回到驳回节点
        /// </summary>
        ToRejectNode,
        /// <summary>
        /// 直接到达结束节点
        /// </summary>
        ToEndNode,
    }
}
